package br.edu.ufcg.dsc.compiladores.validation;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import br.edu.ufcg.dsc.compiladores.pascal.STATEMENT_PART;
import br.edu.ufcg.dsc.compiladores.pascal.block;
import br.edu.ufcg.dsc.compiladores.pascal.constant_definition;
import br.edu.ufcg.dsc.compiladores.pascal.formal_parameter_list;
import br.edu.ufcg.dsc.compiladores.pascal.function_declaration;
import br.edu.ufcg.dsc.compiladores.pascal.procedure_declaration;
import br.edu.ufcg.dsc.compiladores.pascal.procedure_statement;
import br.edu.ufcg.dsc.compiladores.pascal.variable;
import br.edu.ufcg.dsc.compiladores.pascal.variable_declaration;

public class RepresentacaoIntermediaria {
	private static final RepresentacaoIntermediaria INSTANCE = new RepresentacaoIntermediaria();
	private Map<variable, String> variableMap;
	private Map<procedure_declaration, String> procedureMap;
	private Map<function_declaration, String> functionMap;
	private Map<constant_definition, String> constantMap;
	private Map<variable_declaration, List<String>> variableDecMap;
	private Map<formal_parameter_list, List<String>> formalParameterListMap;
	private Map<procedure_statement, String> procedureStatementMap;
	private List<procedure_declaration> procedures;
	private List<function_declaration> functions;
	private STATEMENT_PART mainStatementPart;
	
	private RepresentacaoIntermediaria() {
		variableMap = new HashMap<variable, String>();
		procedureMap = new HashMap<procedure_declaration, String>();
		functionMap = new HashMap<function_declaration, String>();
		constantMap = new HashMap<constant_definition, String>();
		formalParameterListMap = new HashMap<formal_parameter_list, List<String>>();
		procedureStatementMap =new HashMap<procedure_statement, String>();
		procedures = new LinkedList<procedure_declaration>();
		functions = new LinkedList<function_declaration>();
		variableDecMap = new HashMap<variable_declaration, List<String>>();
	}
	
	public void reset(){
		variableMap = new HashMap<variable, String>();
		procedureMap = new HashMap<procedure_declaration, String>();
		functionMap = new HashMap<function_declaration, String>();
		constantMap = new HashMap<constant_definition, String>();
		formalParameterListMap = new HashMap<formal_parameter_list, List<String>>();
		procedureStatementMap =new HashMap<procedure_statement, String>();
		procedures = new LinkedList<procedure_declaration>();
		functions = new LinkedList<function_declaration>();
		variableDecMap = new HashMap<variable_declaration, List<String>>();
		mainStatementPart = null;
	}
	
	public void putProcedureStatement(procedure_statement node, String name){
		procedureStatementMap.put(node, name);
	}
	
	public String getProcedureStatement(procedure_statement p){
		return procedureStatementMap.get(p);
	}
	
	public void putFormalParameterList(formal_parameter_list parametes, List<String> l){
		formalParameterListMap.put(parametes, l);
	}
	
	public List<String> getFormalParamenterList(formal_parameter_list node){
		return formalParameterListMap.get(node); 
	}
	
	public void putProcedure(procedure_declaration node, String name){
		procedures.add(node);
		this.procedureMap.put(node, name);
	}
	public void putFunction(function_declaration node, String name){
		functions.add(node);
		this.functionMap.put(node, name);
	}
	public void putVariable(variable node, String name){
		System.out.println("putVariable: " + name);
		this.variableMap.put(node, name);
	}
	public void putConstant(constant_definition node, String name){
		System.out.println("putconstdef: " + name);
		this.constantMap.put(node, name);
	}
	public String getProcedure(procedure_declaration node){
		return procedureMap.get(node);
	}
	public String getFunction(function_declaration node){
		return functionMap.get(node);
	}
	public String getVariable(variable node){
		return variableMap.get(node);
	}
	public String getConstant(constant_definition node){
		return constantMap.get(node);
	}
	
	public List<String> getVariableDeclaration(variable_declaration node){
		return variableDecMap.get(node);
	}
	public void putVariableDeclaration(variable_declaration node, List<String> names){
		variableDecMap.put(node, names);
	}
	
	public static RepresentacaoIntermediaria getInstance(){
		return INSTANCE;
	}
	
	public void setMainStatementPart(STATEMENT_PART b){
		this.mainStatementPart = b;
	}
	public STATEMENT_PART getMainStatementPart(){
		return mainStatementPart;
	}
	public List<function_declaration> getFunctions(){
		return functions;
	}
	public List<procedure_declaration> getProcedures(){
		return procedures;
	}

}
